<?php

namespace App\Http\Controllers\forum;

use App\models\forum\Partition;
use App\models\forum\PartitionCategorie;
use App\models\forum\Replie;
use App\models\forum\ReplieVote;
use App\models\forum\Topic;
use App\models\forum\TopicVote;
use App\other\AdminFlag;
use App\other\Notification\Mention;
use App\other\Notification\SendMail;
use App\other\UtilsClass;
use Auth;
use DB;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use Parsedown;
use Purifier;
use Session;
use Validator;
use Illuminate\Validation\Validator AS Valid;

class TopicController extends Controller{

    public function createTopic(){
        $partitions = Partition::getForumPartitions();
        return view('forum.createTopic', compact('partitions'));
    }

    public function submitTopic(Request $request){
        /**
         * array:5 [▼
        "_token" => "DQnbEOEBGie69InwJg9p2aBbwxzaIy5deVBWXEPC"
        "partition_id" => "4"
        "category_id" => "1"
        "title" => "23333333"
        "reply_content" => """
        <p>sdasdsa</p>\r\n
        <p>as</p>\r\n
        <p>dasdas</p>
        """
        ]
         */
        $validator = Validator::make($request->all(),[
            'partition_id'      => 'required|integer|exists:partitions,id',
            'category_id'       => 'required|integer|exists:categories,id',
            'title'             => 'required|max:255',
            'reply_content'     => 'required',
        ]);
        $result = $this->validatorTopic($validator, $request);
        if ($result !== true){
            return $result;
        }
        $topic                  = new Topic();
        $topic->title           = $request->get('title');
        $topic->body            = $this->edBodyToHtml($request->get('reply_content'));
        $topic->body_original   = $request->get('reply_content');
        $topic->category_id     = $request->get('category_id');
        $topic->pid             = $request->get('partition_id');
        $topic->is_reply        = 0;
        $topic->stand_count     = 0;
        $topic->against_count   = 0;
        $topic->reply_count     = 0;
        $topic->click_count     = 0;
        $topic->read_flag       = 0;
        $topic->uid             = Auth::id();
        $topic->save();
        return redirect('/forum/topic/'.$topic->id);
    }

    public function topic($id){
        $topic = Topic::find($id);
        $del = null;
        if (
            empty($topic) ||
            ($topic->is_delete == 1 && Auth::check() && !Auth::user()->roleFlag() & AdminFlag::ADMIN_FLAG_TOPIC) ||
            ($topic->is_delete == 1 && !Auth::check())
        ){
            return view('errors.404');
        }

        if ($topic->is_delete == 1 && Auth::check() == true && Auth::user()->roleFlag() & AdminFlag::ADMIN_FLAG_TOPIC){
            $del = 'yes';
        }
        $topic->click_count++;
        $topic->save();
        $user           = $topic->user;
        $replys         = $topic->replie()->get();
        $categorie      = $topic->categorie()->first();
        $replyVote      = ReplieVote::findReplysVotes($id);
        $votes          = TopicVote::getVotes($topic->id);
        $topics         = Topic::where('uid', $topic->uid)
            ->orderby('created_at', 'desc')
            ->paginate(6);
        return view('forum.topic', compact('topic', 'user', 'replys', 'categorie', 'replyVote', 'votes', 'del', 'topics'));
    }

    public function reply(Request $request){
        $validator = Validator::make($request->all(),[
            'topic_id'  => 'required|integer|exists:topics,id',
            'body'      => 'required'
        ]);

        if ($validator->fails()){
            return redirect()
                ->back()
                ->with(['error' => '回复失败']);
        }
        $topic      = Topic::findOrFail($request->get('topic_id'));
        if ($topic->read_flag > Auth::user()->read_flag){
            return redirect()
                ->back()
                ->with(['error' => '无权回复']);
        }
        $topic->reply_count++;
        $replie                  = new Replie();
        if ($replie->createReplie($request->all()) == false){
            return redirect()
                ->back()
                ->with(['error' => '请不要发布重复内容']);
        }
        $replie->topic_id        = $topic->id;
        $replie->index           = $topic->reply_count;
        DB::transaction(function () use($replie, $topic){
            $replie->save();
            $topic->save();
            if (Session::has('atUsers')){
                SendMail::sendReplyNotify(Auth::user(), $replie, Session::get('atUsers')[0]);
            }Session::forget('atUsers');
        });
        return redirect('/forum/topic/'.$topic->id.'#reply'.$replie->index);
    }

    public function edit($id){
        $topic = Topic::find($id);
        if (empty($topic)){
            return view('errors.404');
        }
        if (Auth::user()->userRole->role->flag & AdminFlag::ADMIN_FLAG_TOPIC || Auth::id() == $topic->uid){
            $topic->body = str_replace('src="..', 'src="'.env('APP_CDN'), $topic->body);
            return view('forum.topicEdit', compact('topic'));
        }
        return view('errors.404');
    }

    public function update(Request $request){
        $validator = Validator::make($request->all(), [
            'id'                => 'required|integer|exists:topics,id',
            'partition_id'      => 'required|integer|exists:partitions,id',
            'category_id'       => 'required|integer|exists:categories,id',
            'title'             => 'required|max:255',
            'reply_content'     => 'required',
        ]);

        $result = $this->validatorTopic($validator, $request);
        if ($result !== true){
            return $result;
        }
        $topic                  = Topic::find($request->get('id'));

        if (Auth::user()->userRole->role->flag & AdminFlag::ADMIN_FLAG_TOPIC || Auth::id() == $topic->uid){
            $body                   = $this->edBodyToHtml($request->get('reply_content'));
            $topic->title           = $request->get('title');
            $topic->body            = $body;
            $topic->body_original   = $request->get('reply_content');
            $topic->category_id     = $request->get('category_id');
            $topic->pid             = $request->get('partition_id');
            $topic->chang_user_id   = Auth::id();
            $topic->save();
            return redirect('/forum/topic/'.$request->get('id'));
        }
        return redirect()->back()->with(['_error' => '修改失败']);
    }

    public function replyVote(Request $request){
        $validator = Validator::make($request->all(), [
            'id'        => 'required|integer|exists:replies,id'
        ]);
        if ($validator->fails()){
            return ['code' => '100', 'msg' => '无法投票', 'info' => $validator->getMessageBag()->getMessages()];
        }
        $reply = Replie::find($request->get('id'));
        $vote = ReplieVote::where('uid', Auth::id())->where('replie_id', $request->get('id'))->first();
        if (empty($vote)){
            $vote = new ReplieVote();
            $vote->uid = Auth::id();
            $vote->replie_id = $request->get('id');
            $vote->topic_id  = $reply->topic_id;
            $reply->vote_count++;
            $type = 0;
            $vote->save();
        }else{
            $vote->deleteMe();
            $reply->vote_count--;
            $type=1;
        }
        $reply->save();
        return ['code' => 0, 'msg' => $reply->vote_count, 'type' => $type];
    }

    public function delete(Request $request){
        $validator = Validator::make($request->all(), [
            'id'        => 'required|integer|exists:replies,id'
        ]);
        if ($validator->fails()){
            return ['code' => '100', 'msg' => '无法删除', 'info' => $validator->getMessageBag()->getMessages()];
        }
        Replie::destroy($request->get('id'));
        return ['code' => 0];
    }

    public function vote(Request $request){
        $validator = Validator::make($request->all(),[
            'topic_id'      => 'required|integer|exists:topics,id'
        ]);

        if ($validator->fails()){
            return ['code' => 100, 'msg' => '帖子不存在', 'info'=>UtilsClass::arrayToStringForItem($validator->getMessageBag()->getMessages())];
        }
        $topic = Topic::find($request->get('topic_id'));
        if (Auth::user()->userRole->role->flag & $topic->read_flag || $topic->read_flag == 0){
            $vote = TopicVote::where('uid', Auth::id())->where('topic_id', $request->get('topic_id'))->first();
            if (empty($vote)){
                $vote = new TopicVote();
                $vote->uid = Auth::id();
                $vote->topic_id = $topic->id;
                $vote->save();
                return ['code'=> '0', 'type' => 1, 'msg' => ['uid' => Auth::id(), 'avatar' => Auth::user()->profile]];
            }else{
                $vote->deleteMe();
                return ['code'=> '0', 'type' => 0, 'msg' => ['uid' => Auth::id()]];
            }
        }
        return 233;
    }

    private function validatorTopic(Valid $validator, Request $request){
        if ($validator->fails()){
            return redirect()
                ->back()
                ->with(['_error' => UtilsClass::arrayToStringForItem($validator->getMessageBag()->getMessages())]);
        }

        $p = PartitionCategorie::where('pid', $request->get('partition_id'))
            ->where('cid', $request->get('category_id'))->first();

        if (empty($p)){
            return redirect()->back()->with(['error' => '板块和帖子类型不匹配']);
        }
        return true;
    }

    private function edBodyToHtml($data){
        $mention                = new Mention();
        $parsedown              = new Parsedown();
        $body                   = $parsedown->text($mention->parse($data));
        return Purifier::clean($body, 'user_topic_body');
    }
}
